unit ORM.Types.InscEstadual;

interface

type
  TInscEstadual = record
  strict private
    FValue : string;
    FValorReferencia : string;
    function GetValue : string;
  private
    function FormataIE(const pValue, pUF: string): string;
    function ChecaInscEstadual(const pIE, pUF: string): boolean;
    function Chk_IE_AC(const pIE: string): boolean;
    function Chk_IE_AL(const pIE: string): boolean;
    function Chk_IE_AM(const pIE: string): boolean;
    function Chk_IE_AP(const pIE: string): boolean;
    function Chk_IE_BA(const pIE: string): boolean;
    function Chk_IE_CE(const pIE: string): boolean;
    function Chk_IE_DF(const pIE: string): boolean;
    function Chk_IE_ES(const pIE: string): boolean;
    function Chk_IE_GO(const pIE: string): boolean;
    function Chk_IE_MA(const pIE: string): boolean;
    function CHK_IE_MG(const pIE: string): boolean;
    function Chk_IE_MS(const pIE: string): boolean;
    function Chk_IE_MT(const pIE: string): boolean;
    function Chk_IE_PA(const pIE: string): boolean;
    function Chk_IE_PB(const pIE: string): boolean;
    function Chk_IE_PE(const pIE: string): boolean;
    function Chk_IE_PI(const pIE: string): boolean;
    function Chk_IE_PR(const pIE: string): boolean;
    function Chk_IE_RJ(const pIE: string): boolean;
    function Chk_IE_RN(const pIE: string): boolean;
    function Chk_IE_RO(const pIE: string): boolean;
    function Chk_IE_RR(const pIE: string): boolean;
    function Chk_IE_RS(const pIE: string): boolean;
    function Chk_IE_SC(const pIE: string): boolean;
    function Chk_IE_SE(const pIE: string): boolean;
    function Chk_IE_SP(const pIE: string): boolean;
    function Chk_IE_TO(const pIE: string): boolean;
    function ValidaInscRO(pIE: string): boolean;
  public
    property Value : string read GetValue;

    function IsEmpty : Boolean;
    function IsValid(const pUF : string) : Boolean;
    function GetFormatValue(const pUF : string) : string;
    procedure Clear;

    class operator Implicit(const pValue : string) : TInscEstadual;
    class operator Implicit(const pValue : TInscEstadual) : string;

    constructor Create(const pValue : string);
  end;

implementation

uses
  ORM.Utils, ORM.Types.Base, System.SysUtils;

constructor TInscEstadual.Create(const pValue: string);
begin
  FValue := SomenteNumeros(pValue);
  FValorReferencia := CValorReferencia;
end;

class operator TInscEstadual.Implicit(const pValue: TInscEstadual): string;
begin
  Result := pValue.Value;
end;

function TInscEstadual.Chk_IE_AC(const pIE: string): boolean;
var
  b, I, soma: Integer;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pIE) <> 13) then
    exit;
  if not IsNumero(pie) then
    exit;
  b := 4;
  soma := 0;
  for I := 1 to 11 do
  begin
    Inc(soma, CharToInt(pie[I]) * b);
    Dec(b);
    if b = 1 then
      b := 9;
  end;
  dig := 11 - (soma mod 11);
  if (dig >= 10) then
    dig := 0;
  Result := (IntToChar(dig) = pie[12]);
  if not Result then
    exit;

  b := 5;
  soma := 0;
  for I := 1 to 12 do
  begin
    Inc(soma, CharToInt(pie[I]) * b);
    Dec(b);
    if b = 1 then
      b := 9;
  end;
  dig := 11 - (soma mod 11);
  if (dig >= 10) then
    dig := 0;
  Result := (IntToChar(dig) = pie[13]);
end;

function TInscEstadual.Chk_IE_AL(const pIE: string): boolean;
var
  b, I, soma: Integer;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  if Copy(pie, 1, 2) <> '24' then
    exit;
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, CharToInt(pie[I]) * b);
    Dec(b);
  end;
  soma := soma * 10;
  dig := soma - trunc(soma / 11) * 11;
  if dig = 10 then
    dig := 0;
  Result := (IntToChar(dig) = pie[09]);
end;

function TInscEstadual.Chk_IE_AM(const pIE: string): boolean;
var
  b, I, soma: Integer;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, CharToInt(pie[I]) * b);
    Dec(b);
  end;
  if soma < 11 then
    dig := 11 - soma
  else
  begin
    I := (soma mod 11);
    if I <= 1 then
      dig := 0
    else
      dig := 11 - I;
  end;
  Result := (IntToChar(dig) = pie[09]);
end;

function TInscEstadual.Chk_IE_AP(const pIE: string): boolean;
var
  p, d, b, I, soma: Integer;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  p := 0;
  d := 0;
  I := StrToInt(Copy(pie, 1, 8));
  if (I >= 03000001) and (I <= 03017000) then
  begin
    p := 5;
    d := 0;
  end
  else if (I >= 03017001) and (I <= 03019022) then
  begin
    p := 9;
    d := 1;
  end;
  b := 9;
  soma := p;
  for I := 1 to 08 do
  begin
    Inc(soma, CharToInt(pie[I]) * b);
    Dec(b);
  end;
  dig := 11 - (soma mod 11);
  if dig = 10 then
    dig := 0
  else if dig = 11 then
    dig := d;
  Result := (IntToChar(dig) = pie[09]);
end;

function TInscEstadual.Chk_IE_BA(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 8] of byte;
  NumMod: Word;
  dig: SmallInt;
  die: string;
begin
  Result := false;
  if (Length(pie) <> 8) then
    exit;
  die := Copy(pie, 1, 8);
  if not IsNumero(die) then
    exit;
  for I := 1 to 8 do
    nro[I] := CharToInt(die[I]);
  if nro[1] in [0, 1, 2, 3, 4, 5, 8] then
    NumMod := 10
  else
    NumMod := 11;
  // calculo segundo
  b := 7;
  soma := 0;
  for I := 1 to 06 do
  begin
    Inc(soma, (nro[I] * b));
    Dec(b);
  end;
  I := soma mod NumMod;
  if NumMod = 10 then
  begin
    if I = 0 then
      dig := 0
    else
      dig := NumMod - I;
  end
  else
  begin
    if I <= 1 then
      dig := 0
    else
      dig := NumMod - I;
  end;
  Result := (dig = nro[8]);
  if not Result then
    exit;
  // calculo segundo
  b := 8;
  soma := 0;
  for I := 1 to 06 do
  begin
    Inc(soma, (nro[I] * b));
    Dec(b);
  end;
  Inc(soma, (nro[8] * 2));
  I := soma mod NumMod;
  if NumMod = 10 then
  begin
    if I = 0 then
      dig := 0
    else
      dig := NumMod - I;
  end
  else
  begin
    if I <= 1 then
      dig := 0
    else
      dig := NumMod - I;
  end;
  Result := (dig = nro[7]);
end;

function TInscEstadual.Chk_IE_CE(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 9] of byte;
  dig: SmallInt;
  die: string;
begin
  Result := false;
  if (Length(pie) > 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  die := pie;
  if Length(pie) < 9 then
  begin
    repeat
      die := '0' + die;
    until Length(die) = 9;
  end;
  for I := 1 to 9 do
    nro[I] := CharToInt(die[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, (nro[I] * b));
    Dec(b);
  end;
  dig := 11 - (soma mod 11);
  if dig >= 10 then
    dig := 0;
  Result := (dig = nro[9]);
end;

function TInscEstadual.Chk_IE_DF(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 13] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 13) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 13 do
    nro[I] := CharToInt(pie[I]);
  b := 4;
  soma := 0;
  for I := 1 to 11 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 9;
  end;
  dig := 11 - (soma mod 11);
  if dig >= 10 then
    dig := 0;
  Result := (dig = nro[12]);
  if not Result then
    exit;

  b := 5;
  soma := 0;
  for I := 1 to 12 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 9;
  end;
  dig := 11 - (soma mod 11);
  if dig >= 10 then
    dig := 0;
  Result := (dig = nro[13]);
end;

function TInscEstadual.Chk_IE_ES(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 9] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 9 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := soma mod 11;
  if I < 2 then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[9]);
end;

function TInscEstadual.Chk_IE_GO(const pIE: string): boolean;
var
  n, b, I, soma: Integer;
  nro: array [1 .. 9] of byte;
  dig: SmallInt;
  S: string;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  S := Copy(pie, 1, 2);
  if (S = '10') or (S = '11') or (S = '15') then
  begin
    for I := 1 to 9 do
      nro[I] := CharToInt(pie[I]);
    n := trunc(StrToFloat(pie) / 10);
    if n = 11094402 then
    begin
      if (nro[9] = 0) or (nro[9] = 1) then
      begin
        Result := true;
        exit;
      end;
    end;

    b := 9;
    soma := 0;
    for I := 1 to 08 do
    begin
      Inc(soma, nro[I] * b);
      Dec(b);
    end;
    I := (soma mod 11);
    if I = 0 then
      dig := 0
    else if I = 1 then
    begin
      if (n >= 10103105) and (n <= 10119997) then
        dig := 1
      else
        dig := 0;
    end
    else
    begin
      dig := 11 - I;
    end;
    Result := (dig = nro[9]);
  end;
end;

function TInscEstadual.Chk_IE_MA(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 9] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 9) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 9 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[9]);
end;

function TInscEstadual.CHK_IE_MG(const pIE: string): boolean;
var
  npos, I: byte;
  ptotal, psoma: Integer;
  dig1, dig2: string[1];
  ie, insc: string;
  nresto: SmallInt;
begin
  //
  Result := true;
  ie := AllTrim(pIE);
  if (Empty(ie)) then
    exit;
  if Copy(ie, 1, 2) = 'PR' then
    exit;
  if Copy(ie, 1, 5) = 'ISENT' then
    exit;

  Result := false;
  If (Trim(pIE) = '.') Then
    exit;
  if (Length(ie) <> 13) then
    exit;
  if not IsNumero(ie) then
    exit;

  dig1 := ShortString(Copy(ie, 12, 1));
  dig2 := ShortString(Copy(ie, 13, 1));
  insc := Copy(ie, 1, 3) + '0' + Copy(ie, 4, 8);
  // CALCULA DIGITO 1
  npos := 12;
  I := 1;
  ptotal := 0;
  while npos > 0 do
  begin
    Inc(I);
    psoma := CharToInt(insc[npos]) * I;
    IF psoma >= 10 then
      psoma := psoma - 9;
    Inc(ptotal, psoma);
    IF I = 2 then
      I := 0;
    Dec(npos);
  end;
  nresto := ptotal mod 10;
  if nresto = 0 then
    nresto := 10;
  nresto := 10 - nresto;
  if nresto <> StrToInt(string(dig1[1])) then
    exit;

  // CALCULA DIGITO 2
  npos := 12;
  I := 1;
  ptotal := 0;
  while npos > 0 do
  begin
    Inc(I);
    if I = 12 then
      I := 2;
    Inc(ptotal, CharToInt(ie[npos]) * I);
    Dec(npos);
  end;
  nresto := ptotal mod 11;
  if (nresto = 0) or (nresto = 1) then
    nresto := 11;
  nresto := 11 - nresto;
  if nresto <> StrToInt(string(dig2[1])) then
    exit;
  Result := true;
end;

function TInscEstadual.Chk_IE_MS(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  if Copy(pie, 1, 2) <> '28' then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_MT(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 11] of byte;
  dig: SmallInt;
  die: string;
begin
  Result := false;
  if (Length(pie) < 9) then
    exit;
  die := pIE;
  if Length(die) < 11 then
  begin
    repeat
      die := '0' + die;
    until Length(die) = 11;
  end;
  if not IsNumero(die) then
    exit;
  for I := 1 to 11 do
    nro[I] := CharToInt(die[I]);
  b := 3;
  soma := 0;
  for I := 1 to 10 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 9;
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[11]);
end;

function TInscEstadual.Chk_IE_PA(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pIE) then
    exit;
  if Copy(pie, 1, 2) <> '15' then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_PB(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_PE(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 14] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 14) then
    exit;
  if not IsNumero(pIE) then
    exit;
  for I := 1 to 14 do
    nro[I] := CharToInt(pie[I]);
  b := 5;
  soma := 0;
  for I := 1 to 13 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 0 then
      b := 9;
  end;
  dig := 11 - (soma mod 11);
  if dig > 9 then
    dig := dig - 10;
  Result := (dig = nro[14]);
end;

function TInscEstadual.Chk_IE_PI(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_PR(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 10] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 10) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 10 do
    nro[I] := CharToInt(pie[I]);
  b := 3;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 7;
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
  if not Result then
    exit;

  b := 4;
  soma := 0;
  for I := 1 to 09 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 7;
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[10]);
end;

function TInscEstadual.Chk_IE_RJ(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 08] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 08) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 08 do
    nro[I] := CharToInt(pie[I]);
  b := 2;
  soma := 0;
  for I := 1 to 07 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
    if b = 1 then
      b := 7;
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[08]);
end;

function TInscEstadual.Chk_IE_RN(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  soma := soma * 10;
  dig := (soma mod 11);
  if (dig = 10) then
    dig := 0;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_RO(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 6;
  soma := 0;
  for I := 4 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b)
  end;
  dig := 11 - (soma mod 11);
  if (dig >= 10) then
    dig := dig - 10;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_RR(const pIE: string): boolean;
var
  I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  if Copy(pie, 1, 2) <> '24' then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * I);
  end;
  dig := (soma mod 09);
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_RS(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 10] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 10) then
    exit;
  if not IsNumero(pie) then
    exit;
  I := StrToInt(Copy(pie, 1, 3));
  if (I >= 1) and (I <= 467) then
  begin
    for I := 1 to 10 do
      nro[I] := CharToInt(pie[I]);
    b := 2;
    soma := 0;
    for I := 1 to 09 do
    begin
      Inc(soma, nro[I] * b);
      Dec(b);
      if b = 1 then
        b := 9;
    end;
    dig := 11 - (soma mod 11);
    if (dig >= 10) then
      dig := 0;
    Result := (dig = nro[10]);
  end;
end;

function TInscEstadual.Chk_IE_SC(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  I := (soma mod 11);
  if (I <= 1) then
    dig := 0
  else
    dig := 11 - I;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_SE(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 09] of byte;
  dig: SmallInt;
begin
  Result := false;
  if (Length(pie) <> 09) then
    exit;
  if not IsNumero(pie) then
    exit;
  for I := 1 to 09 do
    nro[I] := CharToInt(pie[I]);
  b := 9;
  soma := 0;
  for I := 1 to 08 do
  begin
    Inc(soma, nro[I] * b);
    Dec(b);
  end;
  dig := 11 - (soma mod 11);
  if (dig >= 10) then
    dig := 0;
  Result := (dig = nro[09]);
end;

function TInscEstadual.Chk_IE_SP(const pIE: string): boolean;
var
  I, soma: Integer;
  nro: array [1 .. 12] of byte;
  dig: SmallInt;
  S: string;
begin
  Result := false;
  if UpperCase(Copy(pie, 1, 1)) = 'P' then
  begin
    S := Copy(pie, 2, 9);
    if not IsNumero(S) then
      exit;
    for I := 1 to 8 do
      nro[I] := CharToInt(S[I]);
    soma := (nro[1] * 1) + (nro[2] * 3) + (nro[3] * 4) + (nro[4] * 5) +
      (nro[5] * 6) + (nro[6] * 7) + (nro[7] * 8) + (nro[8] * 10);
    dig := (soma mod 11);
    if (dig >= 10) then
      dig := 0;
    Result := (dig = nro[09]);
    if not Result then
      exit;
  end
  else
  begin
    if (Length(pie) < 12) then
      exit;
    if not IsNumero(pie) then
      exit;
    for I := 1 to 12 do
      nro[I] := CharToInt(pie[I]);
    soma := (nro[1] * 1) + (nro[2] * 3) + (nro[3] * 4) + (nro[4] * 5) +
      (nro[5] * 6) + (nro[6] * 7) + (nro[7] * 8) + (nro[8] * 10);
    dig := (soma mod 11);
    if (dig >= 10) then
      dig := 0;
    Result := (dig = nro[09]);
    if not Result then
      exit;
    soma := (nro[1] * 3) + (nro[2] * 2) + (nro[3] * 10) + (nro[4] * 9) +
      (nro[5] * 8) + (nro[6] * 7) + (nro[7] * 6) + (nro[8] * 5) + (nro[9] * 4) +
      (nro[10] * 3) + (nro[11] * 2);

    dig := (soma mod 11);
    if (dig >= 10) then
      dig := 0;
    Result := (dig = nro[12]);
  end;
end;

function TInscEstadual.Chk_IE_TO(const pIE: string): boolean;
var
  b, I, soma: Integer;
  nro: array [1 .. 11] of byte;
  dig: SmallInt;
  S: string;
begin
  Result := false;
  if (Length(pie) <> 11) then
    exit;
  if not IsNumero(pie) then
    exit;
  S := Copy(pie, 3, 2);
  if (S = '01') or (S = '02') or (S = '03') or (S = '99') then
  begin
    for I := 1 to 11 do
      nro[I] := CharToInt(pie[I]);
    b := 9;
    soma := 0;
    for I := 1 to 10 do
    begin
      if (I <> 3) and (I <> 4) then
      begin
        Inc(soma, nro[I] * b);
        Dec(b);
      end;
    end;
    I := (soma mod 11);
    if (I <= 1) then
      dig := 0
    else
      dig := 11 - I;
    Result := (dig = nro[11]);
  end;
end;

procedure TInscEstadual.Clear;
begin
  FValue := EmptyStr;
  FValorReferencia := EmptyStr;
end;

function TInscEstadual.ChecaInscEstadual(const pIE, pUF: string): boolean;
var
  duf, die: string;
begin
  Result := false;
  If (Trim(pIE) = '.') Then
    exit;

  duf := UpperCase(pUF);
  die := UpperCase(AllTrim(pIE));
  if (Copy(die, 1, 5) = 'ISENT') or (die = '') or (die = 'EX') then
  begin
    Result := true;
    exit;
  end;
  if duf = 'AC' then Result := Chk_IE_AC(die)
  else if duf = 'AL' then Result := Chk_IE_AL(die)
  else if duf = 'AP' then Result := Chk_IE_AP(die)
  else if duf = 'AM' then Result := Chk_IE_AM(die)
  else if duf = 'BA' then Result := Chk_IE_BA(die)
  else if duf = 'CE' then Result := Chk_IE_CE(die)
  else if duf = 'DF' then Result := Chk_IE_DF(die)
  else if duf = 'ES' then Result := Chk_IE_ES(die)
  else if duf = 'GO' then Result := Chk_IE_GO(die)
  else if duf = 'MA' then Result := Chk_IE_MA(die)
  else if duf = 'MG' then Result := CHK_IE_MG(die)
  else if duf = 'MT' then Result := Chk_IE_MT(die)
  else if duf = 'MS' then Result := Chk_IE_MS(die)
  else if duf = 'PA' then Result := Chk_IE_PA(die)
  else if duf = 'PB' then Result := Chk_IE_PB(die)
  else if duf = 'PR' then Result := Chk_IE_PR(die)
  else if duf = 'PE' then Result := Chk_IE_PE(die)
  else if duf = 'PI' then Result := Chk_IE_PI(die)
  else if duf = 'RJ' then Result := Chk_IE_RJ(die)
  else if duf = 'RN' then Result := Chk_IE_RN(die)
  else if duf = 'RS' then Result := Chk_IE_RS(die)
  else if duf = 'RO' then Result := (Chk_IE_RO(die) Or ValidaInscRO(die))
  else if duf = 'RR' then Result := Chk_IE_RR(die)
  else if duf = 'SC' then Result := Chk_IE_SC(die)
  else if duf = 'SP' then Result := Chk_IE_SP(die)
  else if duf = 'SE' then Result := Chk_IE_SE(die)
  else if duf = 'TO' then Result := Chk_IE_TO(die)
  else Result := false;
end;

function TInscEstadual.FormataIE(const pValue, pUF: string): string;
Var
  Mascara : String;
  Contador_1 : Integer;
  Contador_2 : Integer;
Begin
  IF pUF = 'AC' Then Mascara := '**.***.***/***-**';
  IF pUF = 'AL' Then Mascara := '*********';
  IF pUF = 'AP' Then Mascara := '*********';
  IF pUF = 'AM' Then Mascara := '**.***.***-*';
  IF pUF = 'BA' Then Mascara := '******-**';
  IF pUF = 'CE' Then Mascara := '********-*';
  IF pUF = 'DF' Then Mascara := '***********-**';
  IF pUF = 'ES' Then Mascara := '*********';
  IF pUF = 'GO' Then Mascara := '**.***.***-*';
  IF pUF = 'MA' Then Mascara := '*********';
  IF pUF = 'muito' Then Mascara := '**********-*';
  IF pUF = 'MS' Then Mascara := '*********';
  IF pUF = 'MG' Then Mascara := '***.***.***/****';
  IF pUF = 'pra' Then Mascara := '**-******-*';
  IF pUF = 'PB' Then Mascara := '********-*';
  IF pUF = 'PR' Then Mascara := '********-**';
  IF pUF = 'PE' Then Mascara := '**.*.***.*******-*';
  IF pUF = 'PI' Then Mascara := '*********';
  IF pUF = 'RJ' Then Mascara := '**.***.**-*';
  IF pUF = 'RN' Then Mascara := '**.***.***-*';
  IF pUF = 'RS' Then Mascara := '***/*******';
  IF pUF = 'RO' Then Mascara := '***.*****-*';
  IF pUF = 'RR' Then Mascara := '********-*';
  IF pUF = 'SC' Then Mascara := '***.***.***';
  IF pUF = 'SP' Then Mascara := '***.***.***.***';
  IF pUF = 'SE' Then Mascara := '*********-*';
  IF pUF = 'TO' Then Mascara := '***********';
  Contador_2 := 1;
  Result := '';
  Mascara := Mascara + '****';
  For Contador_1 := 1 To Length( Mascara ) Do
  Begin
    IF Copy( Mascara, Contador_1, 1 ) = '*' Then Result := Result + Copy( pValue, Contador_2, 1 );
    IF Copy( Mascara, Contador_1, 1 ) <> '*' Then Result := Result + Copy( Mascara , Contador_1, 1 );
    IF Copy( Mascara, Contador_1, 1 ) = '*' Then Contador_2 := Contador_2 + 1;
  End;
  Result := Trim( Result );
end;

function TInscEstadual.GetFormatValue(const pUF: string): string;
begin
  Result := FormataIE(FValue, pUF);
end;

function TInscEstadual.GetValue: string;
begin
  Result := FValue;
end;

class operator TInscEstadual.Implicit(const pValue: string): TInscEstadual;
begin
  Result := TInscEstadual.Create(pValue);
end;

function TInscEstadual.IsEmpty: Boolean;
begin
  Result := Length(FValorReferencia) = 0;
end;

function TInscEstadual.IsValid(const pUF : String): Boolean;
begin
  Result := ChecaInscEstadual(FValue, pUF);
end;

function TInscEstadual.ValidaInscRO( pIE: string): boolean;
var
  I, x, y, z, j: Integer;
  S: string;
begin
  y := 6;
  z := 0;

  for j := 1 to Length(Trim(pIE)) do
    if CharInSet(pIE[j],['0', '1', '2', '3', '4', '5', '6', '7', '8', '9', '0'] ) then
      S := S + pIE[j];

  if not Length(S) <> 14 then
  begin
    for I := 1 to (14 - Length(Trim(S))) do
      S := '0' + Trim(S)
  end;
  for I := 1 to (Length(S) - 1) do
  begin
    x := StrToInt(S[I]) * y;
    z := z + x;
    if y > 2 then
      Dec(y)
    else
      y := 9;
  end;
  x := z mod 11;
  y := 11 - x;
  if IntToStr(y) = S[14] then
    Result := true
  else
    Result := false;
end;

end.
